package projects

import (
	"encoding/json"
	"fmt"
	"github.com/beego/beego/v2/core/validation"
	"github.com/beego/beego/v2/server/web/pagination"
	"log"
	"strconv"
	"strings"
	"xpms/controllers"
	"xpms/cores"
	"xpms/cores/utils"
)

// 需求管理
type NeedsProjectController struct {
	controllers.BaseController
}

// @Title 分页查询项目需求数据
// @Description 分页查询项目需求数据
// @Param	id		path 	string	true		"项目id"
// @Param	p		query 	int	true		"第几页"
// @Param	pageoffset		query 	int			"每页数"
// @Param	filter		query 	string			"create:我创建 accept:指派给我"
// @Param	status		query 	[]string			"状态"
// @Param	stage		query 	[]string			"阶段"
// @Param	acceptid		query 	[]string			"指派人"
// @Param	keywords		query 	string			"关键字"
// @Success 200 {object} projects.ProjectsNeeds   int   int  int
// @Failure 403 module not exist
// @router /:id/page [get]
func (u *NeedsProjectController) Page() {
	page, err := u.GetInt("p")
	if err != nil {
		page = 1
	}
	offset, err := u.GetInt("pageoffset")
	if err != nil {
		offset = 15
	}
	id, err := u.GetInt64(":id")
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "未选择项目" + err.Error()}
		u.ServeJSON()
		return
	}
	userid := u.BaseController.UserUserId
	filter := u.GetString("filter")
	status := u.GetStrings("status")
	stage := u.GetStrings("stage")
	keywords := u.GetString("keywords")
	acceptid := u.GetStrings("acceptid")
	condArr := make(map[string]interface{})
	if filter == "create" {
		condArr["userid"] = fmt.Sprintf("%d", userid)
	} else {
		condArr["acceptid"] = fmt.Sprintf("%d", userid)
		filter = "accept"
	}
	condArr["filter"] = filter

	condArr["projectid"] = fmt.Sprintf("%d", id)
	condArr["status"] = status
	condArr["stage"] = stage
	condArr["keywords"] = keywords
	condArr["acceptid"] = acceptid
	//countUser := projects.CountNeeds(condArr)
	//paginator := pagination.SetPaginator(u.Ctx, offset, countUser)
	//_, _, modeData := projects.ListProjectNeeds(condArr, page, offset)

	countTest := NeedPageCountExec(condArr, page, offset)
	paginator := pagination.SetPaginator(u.Ctx, offset, countTest)
	modeData := NeedPageExec(condArr, page, offset)

	type data struct {
		Needs    []ProjectsPageeNeeds
		Total    int64
		PageNums int
		Page     int
	}
	d := &data{modeData, paginator.Nums(), paginator.PageNums(), paginator.Page()}
	var responseEntity cores.ResponseEntity
	u.Data["json"] = responseEntity.Build(d).Data
	u.Ctx.Output.Status = responseEntity.StatusCode
	u.ServeJSON()
}

type NeedsDTO struct {
	Projectid   int64 `json:"Projectid,string"`
	Name        string
	Desc        string
	Acceptid    int64 `json:"Acceptid,string"`
	Source      int   `json:"Source,string"`
	Acceptance  string
	Level       int `json:"Level,string"`
	Tasktime    int `json:"Tasktime,string"`
	Attachment  string
	Stage       int `json:"Stage,string"`
	Status      int `json:"Status,string"`
	Xcoordinate float64
	Ycoordinate float64
	Colour      string
	Pneedsid    int64 `json:"Pneedsid,string"`
	Orders      int
	Crosswise   int64 `json:"Crosswise,string"`
	Lengthways  int64 `json:"Lengthways,string"`
	High        int
	Width       int
}

// 如果你的 struct 实现了接口 validation.ValidFormer
// 当 StructTag 中的测试都成功时，将会执行 Valid 函数进行自定义验证
func (u *NeedsDTO) Valid(v *validation.Validation) {
	v.Required(u.Name, "name").Message("需求名称不能为空")
	//v.Max(u.Name, 15, "name").Message("名称不能超过15")
	v.Required(u.Projectid, "Projectid").Message("项目不能为空")
}

// @Title Create needs
// @Description create module
// @Param	body		body 	projects.NeedsDTO	true		"body for needs content"
// @Success 200 {string} projects.ProjectsNeeds.Id
// @Failure 403 body is empty
// @router / [post]
func (u *NeedsProjectController) Create() {
	var dto NeedsDTO
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &dto)
	// 开始校验输入值
	valid := validation.Validation{}
	b, err := valid.Valid(&dto)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	exists := GetProjectNeedsByName(dto.Name, dto.Projectid)
	if !utils.IsEmpty(exists.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "需求重复"}
		u.ServeJSON()
		return
	}
	err = AddNeeds(u.BaseController.UserUserId, dto)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息添加成功"}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息添加失败" + err.Error()}
	}
	u.ServeJSON()
}

// @Title Update Needs
// @Description  Update Needs
// @Param	id		path 	string	true		"Needs id"
// @Param	body		body 	projects.NeedsDTO	true		"body for Needs content"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /:id [put]
func (u *NeedsProjectController) Update() {
	ids, err := u.GetInt64(":id")
	if err != nil || ids <= 0 {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "你选择更新的需求为空"}
		u.ServeJSON()
		return
	}
	var dto NeedsDTO
	err = json.Unmarshal(u.Ctx.Input.RequestBody, &dto)
	// 开始校验输入值
	valid := validation.Validation{}
	b, err := valid.Valid(&dto)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	userss, err1 := GetProjectNeeds(ids)
	if err1 != nil || utils.IsEmpty(userss.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "需求不存在"}
		u.ServeJSON()
		return
	}
	exists := GetProjectNeedsByName(dto.Name, userss.Projectid)
	if !utils.IsEmpty(exists.Id) && userss.Id != exists.Id {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "需求重复"}
		u.ServeJSON()
		return
	}
	pro := new(ProjectsNeeds)
	utils.SimpleCopyProperties(pro, dto)
	err = UpdateNeeds(ids, *pro)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息修改成功", "id": fmt.Sprintf("%d", ids)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息修改失败" + err.Error()}
	}
	u.ServeJSON()
}

// @Title Get
// @Description get needs  by id
// @Param	id		path 	string	true		"The key for needs"
// @Success 200 {object} projects.ProjectsNeeds
// @Failure 403 :id is empty
// @router /:id [get]
func (u *NeedsProjectController) Get() {
	uid := u.GetString(":id")
	if uid != "" {
		var responseEntity cores.ResponseEntity
		int64, err := strconv.ParseInt(uid, 10, 64)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息主键异常:" + err.Error()}
			return
		}
		modeData, err := GetProjectNeeds(int64)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息主键异常:" + err.Error()}
		} else {
			u.Data["json"] = responseEntity.Build(modeData).Data
			u.Ctx.Output.Status = responseEntity.StatusCode
		}
	}
	u.ServeJSON()
}

// @Title Update needs status
// @Description  Update needs status
// @Param	id		path 	string	true		"needs id"
// @Param	status	query 	string	true		"状态"
// @Success 200 {string} 更新成功
// @Failure 403 body is empty
// @router /:id/status [put]
func (u *NeedsProjectController) UpdateStatus() {
	ids, err := u.GetInt64(":id")
	if err != nil || ids <= 0 {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "你选择更新的用户为空"}
		u.ServeJSON()
		return
	}
	status, err := u.GetInt("status")
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "状态为空"}
		u.ServeJSON()
		return
	}
	exist, err1 := GetProjectNeeds(ids)
	if err1 != nil || utils.IsEmpty(exist.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "不存在"}
		u.ServeJSON()
		return
	}
	err = ChangeProjectNeedsStatus(ids, status)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息修改成功", "id": fmt.Sprintf("%d", ids)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息修改失败" + err.Error()}
	}
	u.ServeJSON()
}

// @Title Delete
// @Description get needs  by id
// @Param	id		path 	string	true		"The key for needs"
// @Success 200 {string} 删除成功
// @Failure 403 :id is empty
// @router /:id [delete]
func (u *NeedsProjectController) Delete() {
	uid := u.GetString(":id")
	if uid != "" {
		int64, err := strconv.ParseInt(uid, 10, 64)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息删除失败:" + err.Error()}
			return
		}
		err = DeleteNeed(int64)
		if err == nil {
			u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息删除成功"}
		} else {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息删除失败:" + err.Error()}
		}
	}
	u.ServeJSON()
}

type NeedToPlanDto struct {
	Planid int64 `json:"Planid,string"`
}

// 如果你的 struct 实现了接口 validation.ValidFormer
// 当 StructTag 中的测试都成功时，将会执行 Valid 函数进行自定义验证
func (u *NeedToPlanDto) Valid(v *validation.Validation) {
	v.Required(u.Planid, "Started").Message("请选择计划")
}

// @Title 一键转任务
// @Description   一键转任务
// @Param	body		body 	projects.NeedToPlanDto	true		"body for needs content"
// @Success 200 {string} 一键转计划
// @Failure 403 body is empty
// @router /changed/:id/plan [put]
func (u *NeedsProjectController) ToPlanDto() {
	id, err := u.GetInt64(":id")
	if err != nil || id < 0 {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "未知需求"}
		u.ServeJSON()
		return
	}
	var dto NeedToPlanDto
	err = json.Unmarshal(u.Ctx.Input.RequestBody, &dto)
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "解析json错误" + err.Error()}
		u.ServeJSON()
		return
	}
	// 开始校验输入值
	valid := validation.Validation{}
	b, err := valid.Valid(&dto)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	needs, err := GetProjectNeeds(id)
	if utils.IsEmpty(needs.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "转化任务失败,未获取到需求"}
		return
	}
	nplan, err := GetPlan(dto.Planid)
	if utils.IsEmpty(nplan.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "转化任务失败,未获取到计划"}
		return
	}
	if nplan.Status > 3 {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "转化任务失败,寻找的计划已完成、已取消、已暂停、已关闭"}
		return
	}
	idpk := utils.SnowFlakeId()
	task := new(ProjectsTask)
	task.Planid = dto.Planid
	task.Id = idpk
	task.Classify = 2
	task.Name = needs.Name
	task.Acceptance = needs.Acceptance
	task.Desc = needs.Desc
	task.Userid = u.BaseController.UserUserId
	err = AddTask(u.BaseController.UserUsername, *task)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "转化任务成功,请设置对应信息"}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "转化任务失败:" + err.Error()}
	}
	u.ServeJSON()
}
